﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

namespace UpdateUDMBackService
{
    public class NetworkUtil
    {
        private static string _token = "";
        //private static LogUtil log = new LogUtil("BoschExcelAddin.Utils.NetworkUtil");
        public static string Token
        {
            get
            {
                return _token;
            }
            set
            {
                _token = value;
            }
        }
        /// <summary>
        /// Post方式调用接口
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="url"></param>
        /// <param name="body"></param>
        /// <param name="needAuth"></param>
        /// <returns></returns>
        public static async Task<CXResponse<T>> postAsync<T>(string url, Dictionary<string, object> body) where T : class
        {
            try
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
                HttpWebRequest request = requestCreate(url);

                request.Method = "POST";
                request.ServicePoint.Expect100Continue = false;//必须添加 否则一直超时
                request.ProtocolVersion = HttpVersion.Version11;
                request.Timeout = 300000;
                request.ReadWriteTimeout = 300000;
                request.ContentType = "application/json";
                byte[] buffer = JsonSerializer.SerializeToUtf8Bytes(body);
                request.ContentLength = buffer.Length;
                Stream stream = request.GetRequestStream();
                await stream.WriteAsync(buffer, 0, buffer.Length);
                using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
                {
                    return await processResponse<T>(response);
                }
            }
            catch (WebException ex)
            {
                //log.Error("postAsync:", ex);
                StreamReader streamReader = new StreamReader(ex.Response.GetResponseStream(), System.Text.Encoding.UTF8);
                string responseContent = streamReader.ReadToEnd();
                if (ex.Status == WebExceptionStatus.ProtocolError)
                {
                    if (ex.Response != null)
                    {
                        CXError ret = JsonSerializer.Deserialize<CXError>(responseContent);
                        return new CXResponse<T>(ret, null);
                    }
                }

                return new CXResponse<T>(CXError.serverError, null);
            }
            catch (Exception ex)
            {
                //log.Error("postAsync:", ex);
                return new CXResponse<T>(CXError.unkownError(ex.Message), null);
            }
        }
        public static async Task<CXResponse<T>> processResponse<T>(HttpWebResponse response) where T : class
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

            try
            {
                using (var stream = response.GetResponseStream())
                {
                    HashSet<HttpStatusCode> successCodes = new HashSet<HttpStatusCode>() { HttpStatusCode.OK, HttpStatusCode.Created, HttpStatusCode.Accepted, HttpStatusCode.NoContent };

                    if (!successCodes.Contains(response.StatusCode))
                    {
                        // 返回的是错误信息，则需要通过 CXError 来提取信息
                        CXError ret = await JsonSerializer.DeserializeAsync<CXError>(stream);

                        if (ret != null)
                        {
                            CXResponse<T> responseData = new CXResponse<T>(ret, null);
                            return responseData;
                        }
                        else
                        {
                            CXResponse<T> responseData = new CXResponse<T>(CXError.unkownError(), null);
                            return responseData;
                        }
                    }
                    else
                    {
                        if (response.StatusCode == HttpStatusCode.NoContent)
                        {
                            CXResponse<T> responseData = new CXResponse<T>(null, null);
                            return responseData;
                        }
                        else if (response.StatusCode == HttpStatusCode.Unauthorized)
                        {
                            CXResponse<T> responseData = new CXResponse<T>(CXError.unauthorized, null);
                            return responseData;
                        }
                        else
                        {
                            StreamReader streamReader = new StreamReader(stream, System.Text.Encoding.UTF8);
                            string content = streamReader.ReadToEnd();
                            if (content.Equals("Ok"))
                            {
                                CXResponse<T> responseData = new CXResponse<T>(null, null);
                                return responseData;
                            }
                            T ret;
                            //if (CommonUtil.IsJson(content))
                            {
                                ret = JsonSerializer.Deserialize<T>(content);
                            }
                            //else
                            //{
                            //    ret = content as T;
                            //}

                            if (ret != null)
                            {
                                CXResponse<T> responseData = new CXResponse<T>(null, ret);

                                return responseData;
                            }
                            else
                            {
                                CXResponse<T> responseData = new CXResponse<T>(CXError.unkownType, null);
                                return responseData;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //log.Error("processResponse:", ex);
            }
            return null;
        }
        /// <summary>
        /// 地址信息
        /// </summary>
        public static string APIUrl
        {
            get
            {
                string url = null;
                try
                {
                    if (CommonUtil.IsInDomain())
                    {
                        url = ConfigurationManager.AppSettings["APIUrl"];
                    }
                    else
                    {
                        url = ConfigurationManager.AppSettings["APIOutUrl"];
                    }
                }
                catch (Exception ex)
                {
                    //log.Error("APIUrl:", ex);
                }

                return url;
            }
        }

        /// <summary>
        /// 地址信息
        /// </summary>
        public static string GatewayUrl
        {
            get
            {
                string url = null;

                try
                {
                    url = ConfigurationManager.AppSettings["GatewayUrl"];
                }
                catch (Exception ex)
                {
                    //log.Error("GatewayUrl:", ex);
                }
                return url;
            }
        }

        public static async Task<CXToken> GetToken()
        {
            CXToken cXToken = null;
            var httpClient = new HttpClient();
            // 创建HttpClient对象
            //using (var httpClient = new HttpClient())
            {
                try
                {
                    ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
                    // 添加Authorization头信息
                    httpClient.DefaultRequestHeaders.Authorization =
                        new System.Net.Http.Headers.AuthenticationHeaderValue("Basic",
                        Convert.ToBase64String(Encoding.ASCII.GetBytes($"{ConstUtil.appid}:{ConstUtil.appCode}")));
                    // 发送POST请求并获取响应
                    var response = await httpClient.PostAsync(GatewayUrl, null);

                    // 检查响应是否成功（状态码为200表示成功）
                    if (response.IsSuccessStatusCode)
                    {
                        string responseContent = await response.Content.ReadAsStringAsync();
                        cXToken = JsonSerializer.Deserialize<CXToken>(responseContent);
                    }
                }
                catch (Exception ex)
                {
                    //log.Error("GetToken:", ex);
                }
            }

            return cXToken;
        }
        internal static HttpWebRequest requestCreate(string url)
        {
            HttpWebRequest request = null;

            try
            {
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);//验证服务器证书回调自动验证
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
                //url = NetworkUtil.CXAPIUrl + url;
                request = (HttpWebRequest)WebRequest.Create(url);
                request.Timeout = Timeout.Infinite;
                fillHeaders(request.Headers);
            }
            catch (Exception ex)
            {
                //log.Error("requestCreate:", ex);
            }

            return request;
        }
        /// <summary>
        /// 填充头信息
        /// </summary>
        /// <param name="headers"></param>
        /// <param name="token"></param>
        internal static void fillHeaders(WebHeaderCollection headers)
        {
            //headers.Add("gateway-access-token", "bearer eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI5Y2Y0MTUzZi1lNDI4LTRmOWEtOWY2Yy05Mjc4YjY2MjE3MDYiLCJpYXQiOjE2OTg5NzIxNjksImlzcyI6Ik9hdXRoLWFwaWdhdGV3YXkiLCJzdWIiOiJ1ZG18Y2JkMWExNjc5ZWUwNDgyNjlmMTE0OGI5ZGFmOTMxNzkiLCJleHAiOjE2OTg5NzkzNjl9.etqiPK8YR5uiAoFt7iA8osGQc36PKLmwvGQJrs52WKU");
            headers.Add("gateway-access-token", "bearer " + Token);
        }
        public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {   // 总是接受  
            return true;
        }
        /// <summary>
        /// 获取插件版本信息
        /// </summary>
        /// <param name="localver"></param>
        /// <returns></returns>
        public static async Task<CXResponse<CXVer>> GetExcelVerAsync(string localver)
        {
            Dictionary<string, object> data = new Dictionary<string, object>();
            CXResponse<CXVer> cXResponse = null;
            string jsonString;

            try
            {
                //localver = "2.0.0";
                jsonString = "{\"func\":\"" + "updateTools" + "\",\"user\":\"" +
                    CommonUtil.LoginUserName + "\"," + "\"toolName\":\"" + "UDMBackService" + "\"," +
                    "\"ver\":\"" + localver + "\"}";

                data.Add("id", CommonUtil.GenerateRandomNumber());
                data.Add("UAES_DOMAIN", "N");
                data.Add("eventName", "flask");
                //data.Add("eventName", "excelVerison");
                //data.Add("clientName", "xls");
                data.Add("params", jsonString);
                //data.Add("ver", localver);
                cXResponse = await postAsync<CXVer>(APIUrl, data);
            }
            catch (Exception ex)
            {
                //log.Error("GetExcelVerAsync:", ex);
            }
            return cXResponse;
        }
    }
}
